#include "FileProcessor.h"

string removeHtmlTags(const string &input);
string replaceHtmlEntities(const std::string &input);

vector<RssItem> &FileProcessor::process(string &file_name) {
    // 处理每个网页
    _rss.clear();

    // 1.打开rss文件
    XMLDocument doc;
    XMLError error = doc.LoadFile(file_name.c_str());
    if (error != XML_SUCCESS) {
        cerr << "Failed to open XML file: " << doc.ErrorStr() << "\n";
    }

    // 2.获取频道信息
    XMLElement *pChannel = doc.RootElement()->FirstChildElement("channel");
    if (pChannel == nullptr) {
        cerr << "Failed to find the channel element!" << "\n";
    }

    // 3.循环遍历 <item> 元素
    size_t idx = 0;
    XMLElement *pItem = pChannel->FirstChildElement("item");
    while (pItem != nullptr) {
        XMLElement *pDescription = pItem->FirstChildElement("description");
        if (pDescription == nullptr) {
            pItem = pItem->NextSiblingElement();
            continue;
        }

        string tmpDes = pDescription->GetText();
        string cleanDes = replaceHtmlEntities(removeHtmlTags(tmpDes));
        // 如果cleanDes为空或只包含空字符，跳过当前item
        if (cleanDes.empty() || std::all_of(cleanDes.begin(), cleanDes.end(), ::isspace)) {
            pItem = pItem->NextSiblingElement();
            continue;
        }

        // 保存节点内容信息
        RssItem item;

        string tmpTile = pItem->FirstChildElement("title")->GetText();
        item.title = replaceHtmlEntities(removeHtmlTags(tmpTile));

        item.link = pItem->FirstChildElement("link")->GetText();
        item.description = cleanDes;
        item.id = ++idx;

        _rss.push_back(item);
        // 进入下一个节点
        pItem = pItem->NextSiblingElement();
    }

    // 遍历完成一篇文章
    return _rss;
}

string removeHtmlTags(const string &input) {
    // 使用正则表达式匹配 HTML 标签
    // regex html_tag("<.*?>");
    regex html_tag(R"(<[^>]*>)");
    // 使用正则替换空字符串
    return regex_replace(input, html_tag, "");
}

string replaceHtmlEntities(const std::string &input) {
    // 定义一个HTML实体字符到普通字符的映射
    std::unordered_map<std::string, std::string> entityMap = {
        {"&nbsp;", " "},
        {"&lt;", "<"},
        {"&gt;", ">"},
        {"&amp;", "&"},
        {"&quot;", "\""},
        {"&apos;", "'"},
        // 如果需要可以继续扩展更多的HTML实体
    };

    std::string output = input;

    // 遍历映射表中的所有实体字符，逐一替换
    for (const auto &entity : entityMap) {
        size_t pos = 0;
        // 查找所有该HTML实体字符并替换
        while ((pos = output.find(entity.first, pos)) != std::string::npos) {
            output.replace(pos, entity.first.length(), entity.second);
            pos += entity.second.length(); // 移动位置以避免死循环
        }
    }

    return output;
}